/**
 * Copyright 2018 人人开源 http://www.renren.io
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package com.hs.srm.admin.modules.sys.controller;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.encoding.ShaPasswordEncoder;
import org.springframework.util.Base64Utils;
import org.springframework.util.MultiValueMap;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import cn.hutool.core.util.RandomUtil;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.hs.srm.base.common.annotation.SysLog;
import com.hs.srm.base.common.utils.Constant;
import com.hs.srm.base.common.utils.DomesticUtils;
import com.hs.srm.base.modules.sys.entity.SysAttachmentEntity;
import com.hs.srm.base.modules.sys.entity.SysUserEntity;
import com.hs.srm.base.modules.sys.service.SysAttachmentService;
import com.hs.srm.base.modules.sys.service.SysDeptService;
import com.hs.srm.base.modules.sys.service.SysUserRoleService;
import com.hs.srm.base.modules.sys.service.SysUserService;
import com.hs.srm.base.modules.sys.shiro.ShiroUtils;
import com.hs.srm.common.exception.RRException;
import com.hs.srm.common.utils.DateUtils;
import com.hs.srm.common.utils.FileUtils;
import com.hs.srm.common.utils.PageUtils;
import com.hs.srm.common.utils.R;
import com.hs.srm.common.validator.Assert;
import com.hs.srm.common.validator.ValidatorUtils;
import com.hs.srm.common.validator.group.UpdateGroup;

/**
 * 系统用户
 * 
 * @author chenshun
 * @email sunlightcs@gmail.com
 * @date 2016年10月31日 上午10:40:10
 */
@RestController
@RequestMapping("/sys/user")
public class SysUserController extends AbstractController {

	public static void main(String[] args) {
//		ShaPasswordEncoder passwordEncoder = new ShaPasswordEncoder(1);
//		String password = "admin";
//		String salt = "YzcmCZNvbXocrsz9dm8e";
//		password = passwordEncoder.encodePassword(password, salt);
//		System.out.println(password);
		String password = ShiroUtils.sha256("admin", "YzcmCZNvbXocrsz9dm8e");
		System.out.println(password);
	}

	@Value("${hssrm.file-upload-path}")
	protected String fileUploadPath;
	@Autowired
	private SysUserService sysUserService;
	@Autowired
	private SysUserRoleService sysUserRoleService;
	@Autowired
	private SysDeptService sysDeptService;
	@Autowired
	private SysAttachmentService sysAttachmentService;

	/**
	 * 校验手机号是否存在
	 * @param mobile
	 * @return
	 */
	@RequestMapping("/checkUserMobile")
	@ResponseBody
	public Boolean checkUserMobile(String mobile) {
		SysUserEntity user = this.sysUserService.selectOne(new EntityWrapper<SysUserEntity>().where("mobile={0}",
				mobile));
		return ObjectUtils.isEmpty(user);
	}

	/**
	 * 校验账号是否存在
	 * @param username
	 * @return
	 */
	@RequestMapping("/checkUserName")
	@ResponseBody
	public Boolean checkUserName(String username) {
		SysUserEntity user = this.sysUserService.selectOne(new EntityWrapper<SysUserEntity>().where("username={0}",
				username));
		return ObjectUtils.isEmpty(user);
	}

	/**
	 * 删除用户
	 */
	@SysLog("删除用户")
	@RequestMapping("/delete")
	@RequiresPermissions("sys:user:delete")
	public R delete(@RequestParam(value = "userIds[]") Long[] userIds) {
		if(ArrayUtils.contains(userIds, 1L)) {
			return R.error("超级管理员不能删除");
		}
		if(ArrayUtils.contains(userIds, this.getUserId())) {
			return R.error("当前用户不能删除");
		}

		this.sysUserService.deleteBatchIds(Arrays.asList(userIds));

		return R.ok();
	}

	/**
	 * 获取当前登录用户ID
	 * @return
	 */
	@RequestMapping("/getCurrUserId")
	@ResponseBody
	public R getCurrUserId() {
		return R.ok().put("currUserId", this.getUserId());
	}

	/**
	 * 获取当前登录人数据权限下的用户列表
	 * @return
	 */
	@RequestMapping("/getDataFilterUserList")
	@ResponseBody
	public R getDataFilterUserList() {
		Map<String, Object> params = new HashMap<>();
		List<SysUserEntity> userEntityList = this.sysUserService.selectDataFilterUserList(params);
		return R.ok().put("userList", userEntityList);
	}

	/**
	 * 获取登录的用户信息
	 */
	@RequestMapping("/info")
	public R info() {
		return R.ok().put("result", this.getUser());
	}

	/**
	 * 用户信息
	 */
	@RequestMapping("/info/{userId}")
	@RequiresPermissions("sys:user:info")
	public R info(@PathVariable("userId") Long userId) {
		SysUserEntity user = this.sysUserService.selectById(userId);

		// 获取用户所属的角色列表
		List<Long> roleIdList = this.sysUserRoleService.queryRoleIdList(userId);
		user.setRoleIdList(roleIdList);

		return R.ok().put("user", user);
	}

	/**
	 * 所有用户列表
	 */
	@RequestMapping("/list")
	@RequiresPermissions("sys:user:list")
	public R list(@RequestParam Map<String, Object> params) {
		// 查询用户列表
		PageUtils page = this.sysUserService.queryPage(params);
		return R.ok(page);
	}

	@RequestMapping("/openImagePop")
	public ModelAndView openUserAvatar(@RequestParam String picId) {
		ModelAndView modelAndView = new ModelAndView("common/image_pop");
		modelAndView.addObject("picId", picId);
		return modelAndView;
	}

	/**
	 * 修改登录用户密码
	 */
	@SysLog("修改密码")
	@RequestMapping("/password")
	public R password(String password, String newPassword) {
		Assert.isBlank(newPassword, "新密码不为能空");
		// 修改密码加密方式
		ShaPasswordEncoder passwordEncoder = new ShaPasswordEncoder(1);
		// 原密码
		//password = passwordEncoder.encodePassword(password, this.getUser().getSalt());
		// 新密码
		//newPassword = passwordEncoder.encodePassword(newPassword, this.getUser().getSalt());

		//原密码
		password = ShiroUtils.sha256(password, getUser().getSalt());
		//新密码
		newPassword = ShiroUtils.sha256(newPassword, getUser().getSalt());

		// 更新密码
		boolean flag = this.sysUserService.updatePassword(this.getUserId(), password, newPassword);
		if(!flag) {
			return R.error("原密码不正确");
		}

		return R.ok();
	}

	/**
	 * 返回图片
	 *
	 * @author stylefeng
	 * @Date 2017/5/24 23:00
	 */
	@RequestMapping("/getPic/{pictureId}")
	public void renderPicture(@PathVariable("pictureId") Integer pictureId, HttpServletRequest request,
			HttpServletResponse response) {
		SysAttachmentEntity attachment = this.sysAttachmentService.selectById(pictureId);
		String path = attachment.getPath();
		try {
			byte[] bytes = FileUtils.toByteArray(path);
			response.getOutputStream().write(bytes);
		} catch(Exception e) {
			// 如果找不到图片就返回一个默认图片
			try {
				response.sendRedirect(request.getServletContext().getContextPath() + "/static/img/a1.jpg");
			} catch(IOException e1) {
				e1.printStackTrace();
			}
		}
	}

	/**
	 * 重置密码
	 * @param userId
	 * @return
	 */
	@RequestMapping("/resetPwd/{userId}")
	public R resetPwd(@PathVariable("userId") Long userId) {
		if(Constant.SUPER_ADMIN == userId) {
			return R.error().put("msg", "不能重置超级管理员密码");
		}
		if(this.getUserId().equals(userId)) {
			return R.error().put("msg", "不能重置当前登录账号密码");
		}
		SysUserEntity user = this.sysUserService.selectById(userId);
		// 新密码为123456
		String newPassword = "123456";
		if(ObjectUtils.isEmpty(user.getSalt())) {
			user.setSalt(RandomStringUtils.randomAlphanumeric(20));
		}
		user.setPassword(ShiroUtils.sha256(newPassword, user.getSalt()));
		this.sysUserService.updateById(user);
		return R.ok();
	}

	/**
	 * 保存用户
	 */
	@SysLog("保存用户")
	@RequestMapping("/save")
	@RequiresPermissions("sys:user:save")
	public R save(SysUserEntity user) {
		// 默认密码 123456
		user.setPassword("123456");
		this.sysUserService.save(user);
		return R.ok();
	}

	/**
	 * 跳转至用户编辑页面
	 * @param userId
	 * @return
	 */
	@RequestMapping("/toEdit/{userId}")
	public ModelAndView toEdit(@PathVariable("userId") Long userId) {
		SysUserEntity user = this.sysUserService.selectById(userId);
		// 获取用户所属的角色列表
		List<Long> roleIdList = this.sysUserRoleService.queryRoleIdList(userId);
		user.setRoleIdList(roleIdList);

		// 获取部门信息
		user.setDeptName(this.sysDeptService.selectById(user.getDeptId()).getName());
		ModelAndView modelAndView = new ModelAndView("modules/sys/user/user_edit");
		modelAndView.addObject("user", user);
		return modelAndView;
	}

	@RequestMapping(value = "")
	public ModelAndView toPage(ModelAndView modelAndView) {
		modelAndView.setViewName("modules/sys/user/user_list");
		return modelAndView;
	}

	/**
	 * 禁用
	 * @param userId
	 * @return
	 */
	@RequestMapping("/unUse/{userId}")
	@RequiresPermissions("sys:user:unuse")
	public R unUse(@PathVariable("userId") Long userId) {
		SysUserEntity user = this.sysUserService.selectById(userId);
		user.setStatus(Constant.DataStatus.UNNORMAL.getValue());
		this.sysUserService.updateById(user);
		return R.ok();
	}

	/**
	 * 修改用户
	 */
	@SysLog("修改用户")
	@RequestMapping("/update")
	@RequiresPermissions("sys:user:update")
	public R update(SysUserEntity user) {
		if(Constant.SUPER_ADMIN == user.getUserId()) {
			return R.error().put("msg", "您无权修改超级管理员信息");
		}

		ValidatorUtils.validateEntity(user, UpdateGroup.class);

		this.sysUserService.update(user);

		return R.ok();
	}

	/**
	 * 上传图片
	 */
	@RequestMapping("/upload")
	@ResponseBody
	public R upload(MultipartHttpServletRequest request) {
		MultiValueMap<String, MultipartFile> map = request.getMultiFileMap();
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(new MediaType("text", "plain", Charset.forName("UTF-8")));
		List<MultipartFile> list = map.get("file");// 获取到文件的列表
		List<Long> picId = new ArrayList<>();
		try {
			for(MultipartFile mFile : list) {
				String originalFileName = mFile.getOriginalFilename();// 获取文件名称
				String filePath = DomesticUtils.getFileUrl(originalFileName, this.fileUploadPath);
				byte[] bytes = mFile.getBytes();// 获取字节数组
				FileOutputStream fos = new FileOutputStream(new File(filePath)); // 写出到文件
				fos.write(bytes);
				fos.flush();
				fos.close();

				SysAttachmentEntity attachment = new SysAttachmentEntity();
				attachment.setPath(filePath);
				attachment.setCreateTime(new Date());
				this.sysAttachmentService.insert(attachment);
				picId.add(attachment.getId());
			}
		} catch(IOException e) {
			throw new RRException(e.getMessage(), e);
		}
		return R.ok().put("picId", picId);
	}

	/**
	 * 上传用户头像
	 * @param base64Data
	 * @return
	 */
	@RequestMapping("/uploadAvatar")
	public R uploadAvatar(String base64Data) {
		try {
			String dataPrix = "";
			String data = "";

			if(ObjectUtils.isEmpty(base64Data)) {
				return R.error("上传失败，上传图片数据为空");
			}
			String[] d = base64Data.split("base64,");
			if(d != null && d.length == 2) {
				dataPrix = d[0];
				data = d[1];
			} else {
				return R.error("上传失败，数据不合法");
			}

			// 对数据进行解析，获取文件名和流数据
			String suffix = "";
			if("data:image/jpeg;".equalsIgnoreCase(dataPrix)) {// 编码的jpeg图片数据
				suffix = ".jpg";
			} else if("data:image/x-icon;".equalsIgnoreCase(dataPrix)) {// 编码的icon图片数据
				suffix = ".ico";
			} else if("data:image/gif;".equalsIgnoreCase(dataPrix)) {// 编码的gif图片数据
				suffix = ".gif";
			} else if("data:image/png;".equalsIgnoreCase(dataPrix)) {// 编码的png图片数据
				suffix = ".png";
			} else {
				return R.error("上传图片格式不合法");
			}
			String tempFileName = DateUtils.format(new Date(), "HHmmss") + RandomUtil.randomString(5) + suffix;
			this.logger.debug("生成文件名为：" + tempFileName);

			// 因为BASE64Decoder的jar问题，此处使用spring框架提供的工具包
			byte[] bs = Base64Utils.decodeFromString(data);
			try {
				String fileSavePath = DomesticUtils.getFileUploadPath(this.fileUploadPath);
				// 使用apache提供的工具类操作流
				org.apache.commons.io.FileUtils.writeByteArrayToFile(new File(fileSavePath, tempFileName), bs);

				// 将路径保存至数据库
				SysAttachmentEntity sysAttachmentEntity = new SysAttachmentEntity();
				sysAttachmentEntity.setPath(fileSavePath + tempFileName);
				sysAttachmentEntity.setCreateTime(new Date());
				this.sysAttachmentService.insert(sysAttachmentEntity);
				return R.ok().put("result", sysAttachmentEntity.getId());
			} catch(Exception ee) {
				return R.error("上传失败，写入文件失败，" + ee.getMessage());
			}
		} catch(Exception e) {
			this.logger.debug("上传失败," + e.getMessage());
			return R.error("上传失败," + e.getMessage());
		}
	}

	/**
	 * 启用
	 * @param userId
	 * @return
	 */
	@RequestMapping("/use/{userId}")
	@RequiresPermissions("sys:user:use")
	public R use(@PathVariable("userId") Long userId) {
		SysUserEntity user = this.sysUserService.selectById(userId);
		user.setStatus(Constant.DataStatus.NORMAL.getValue());
		this.sysUserService.updateById(user);
		return R.ok();
	}

	/**
	 * 跳转至个人中心
	 * @param userId
	 * @return
	 */
	@RequestMapping("/toUserCenter/{userId}")
	public ModelAndView userCenter(@PathVariable("userId") Long userId) {
		SysUserEntity user = this.sysUserService.selectById(userId);
		// 获取用户所属的角色列表
		List<Long> roleIdList = this.sysUserRoleService.queryRoleIdList(userId);
		user.setRoleIdList(roleIdList);

		// 获取部门信息
		user.setDeptName(this.sysDeptService.selectById(user.getDeptId()).getName());
		ModelAndView modelAndView = new ModelAndView("modules/sys/user/user_center");
		modelAndView.addObject("user", user);
		return modelAndView;
	}
}
